<?php
/**
 * 帝国常用的方法，这些方法将直接使用静态调用
 */
namespace Plu\Library\Services\Tga;
use Plu\Library\Services\ServiceBase;

final class TgaService extends ServiceBase {
	const CACHE_TIME = 120;

	/**
	 * 只用于内部调用
	 */
	static private function getModel($modelName) {
		$prefix = 'Plu\Library\Models\Tga\Cms';
		$model = $prefix . "\\E" . $modelName;

		if (class_exists($model)) {
			return new $model;
		}
		return false;
	}

	/**
	 * 获取新闻内容信息
	 * @param Int $id content id
	 * @param Int $classId category id
	 * @param Bool $toutf8  need covert utf8?
	 */
	static public function getNewsContent($id, $classId, $toutf8 = true) {
		$guid = sprintf('tganews_content_%s', md5(join("_", func_get_args())));
		$news = self::getCacheHandler()->get($guid, self::CACHE_TIME);

		if (empty($news)) {
			$channeldb = self::getModel('newsclass');
			$channel = $channeldb::findFirst(array(
				'classid = :classid:',
				'bind' => array(
					'classid' => $classId
				)
			));

			if ($channel != false) {
			    $channel = $channel->toArray();
				$tablename = $channel['tbname'];
				$db = self::getModel($tablename);
				$news = $db::findFirst(array(
					'id = :id:',
					'bind' => array(
						'id' => $id
					)
				));
	
				if ($news != false) {
					$news = $news->toArray();
					if ($toutf8) {
						foreach ($news as $key=> $val) {
							$news[$key] = iconv('gbk', 'utf-8', $news[$key]);
						}
					}

					self::getCacheHandler()->save($guid, $news, self::CACHE_TIME);
				}
			}
		}

		return $news;
	}

	/**
	 * 获取当前列表页的总数量
	 * @param $classId 栏目classId, 可以为数组 如array(1367, 1385) 必须要一个相同的类型 否则取出的数据会失败
	 * @param $onlyTitlePic 0为不限制，1为只显示有标题图片的信息。
	 * @param $where sql where语句
	 */
	static public function getNewsCount($classId, $onlyTitlePic = 0, $where = "") {
		if (is_array($classId)) {
			$classIds = $classId;
			$channeldb = self::getModel('newsclass');

			$channels = $channeldb::query()->inWhere('classid', $classIds)->execute();

			if (count($channels) == 0) {
				return 0;
			}

			$tablename = "";
			$sonclass = array();
			for ($i = 0; $i < count($channels); $i++) {
				$channel = $channels[$i]->toArray();
				if (empty($tablename)) {
					$tablename = $channel['tbname'];
				}
				$sc = $channel['sonclass'];
				if ($sc) {
					$sonclass = array_merge($sonclass, explode("|", trim($sc, "|")));
				} else {
					$sonclass[] = $channel['classid'];
				}
			}

			$db = self::getModel($tablename);
		} else {
			$channeldb = self::getModel('newsclass');
			$channel = $channeldb::findFirst(array(
				'classid = :classid:',
				'bind'  => array(
					'classid' => $classId
				)
			));

			if ( $channel === false) {
				return 0;
			}

			$channel = $channel->toArray();
			$tablename = $channel['tbname'];
			$db = self::getModel($tablename);
			//根据classid 获得表名
			$sonclass = $channel['sonclass'];
		}

		$params = [];
		$sql    = [];

		if ($sonclass) {
			if (is_string($sonclass)) {
				$sonclass = explode("|", trim($sonclass, "|"));
			}
			$_sql = [];
			for ($c = 0, $len = count($sonclass); $c < $len; $c++) {
				$p = "r{$c}";
				$_sql[] = " classid = :{$p}: ";
				$params[$p] = $sonclass[$c];
			}
			$sql[] = '(' . join(' OR ', $_sql) . ')';
		} else {
			$params['classid'] = $classId;
			$sql[] = 'classid = :classid:';
		}

		if (!empty($where)) {
			$sql[] = $where;
		}
		if ($onlyTitlePic) {
			$sql[] = '`titlepic` != ""';
		}
		$sql = join(" AND ", $sql);

		$count = $db::count(array(
			$sql,
			"bind"	=> $params
		));
	
		return $count;
	}

	//栏目ID/专题ID,显示条数,操作类型,只显示有标题图片,附加SQL条件,显示排序}
	/**
	 * 从帝国后台获取数据
	 * @param $classId 栏目classId, 可以为数组 如array(1367, 1385) 必须要一个相同的类型 否则取出的数据会失败
	 * @param $count 显示记录数量
	 * @param $action 具体看操作类型说明。
	 * @param $onlyTitlePic 0为不限制，1为只显示有标题图片的信息。
	 * @param $where sql where语句
	 * @param $orderby $排序
	 */
	static public function getNewsList($classId, $count=5, $action=0, $onlyTitlePic=0, $where="", $orderby=" id desc", $toutf8=true) {
		$guid = sprintf("tganews_list_%s", md5(json_encode(func_get_args())));
		$news = self::getCacheHandler()->get($guid, self::CACHE_TIME);

		if (empty($news)) {
			//分析获取的栏目是否是父栏目
			if (is_array($classId)) {
				$classIds = $classId;
				$channeldb = self::getModel('newsclass');

				$channels = $channeldb::query()->inWhere('classid', $classIds)->execute();

				if (count($channels) == 0) {
					return $news;
				}

				$tablename = "";
				$sonclass = array();
				for ($i = 0; $i < count($channels); $i++) {
					$channel = $channels[$i]->toArray();
					if (empty($tablename)) {
						$tablename = $channel['tbname'];
					}
					$sc = $channel['sonclass'];
					if ($sc) {
						$sonclass = array_merge($sonclass, explode("|", trim($sc, "|")));
					} else {
						$sonclass[] = $channel['classid'];
					}
				}

				$db = self::getModel($tablename);
			} else {
				$channeldb = self::getModel('newsclass');
				$channel = $channeldb::findFirst(array(
					'classid = :classid:',
					'bind'  => array(
						'classid' => $classId
					)
				));

				if ( $channel === false) {
					return $news;
				}

				$channel = $channel->toArray();
				$tablename = $channel['tbname'];
				$db = self::getModel($tablename);
				//根据classid 获得表名
				$sonclass = $channel['sonclass'];
			}

			$params = [];
			$sql    = [];

			if ($sonclass) {
				if (is_string($sonclass)) {
					$sonclass = explode("|", trim($sonclass, "|"));
				}
				$_sql = [];
				for ($c = 0, $len = count($sonclass); $c < $len; $c++) {
					$p = "r{$c}";
					$_sql[] = " classid = :{$p}: ";
					$params[$p] = $sonclass[$c];
				}
				$sql[] = '(' . join(' OR ', $_sql) . ')';
			} else {
				$params['classid'] = $classId;
				$sql[] = 'classid = :classid:';
			}

			if (!empty($where)) {
				$sql[] = $where;
			}
			if ($onlyTitlePic) {
				$sql[] = 'titlepic != ""';
			}
			$sql = join(" AND ", $sql);

			$start = 0;
			$limit = 5;
			if (is_array($count) && count($count) == 2) {
				$start = intval($count[0]);
				$limit = intval($count[1]);
			} elseif (is_numeric($count)) {
				$limit = $count;
			}

			$r = $db::find(array(
				$sql,
				"bind"	=> $params,
				"limit" => $limit,
				"offset" => $start,
				"order" => $orderby
			));

			if (count($r) == 0) {
				return $news;
			}

			$news = array();
			$r = $r->toArray();
			for ($i = 0, $len = count($r); $i < $len; $i++) {
				$item = $r[$i];
				if ($toutf8) {
					foreach ($item as $key=> $val) {
						$item[$key] = iconv('gbk', 'utf-8', $item[$key]);
					}
				}

				$news[] = $item;
			}

			//save
			self::getCacheHandler()->save($guid, $news, self::CACHE_TIME);
		}

		return $news;
	}

	/**
	 * 获取轮播图，根据开始时间 结束时间等等因子来排序
	 */
	static public function getRollNews($classid, $limit) {
		$news = self::getNewsList($classid, $limit, 0, 1, "starttime <= NOW() AND (stoptime >= NOW() OR stoptime = '0000-00-00 00:00:00')", '_index DESC, id DESC');

		return $news;
	}

	/**
	 * 生产新闻链接
	 */
	static public function getNewsUrl($url, $prefix, $newspath = '', $id = '') {
		if (!empty($url)) {
			return $url;
		}

		if (empty($url) && isset($newspath) && isset($id)) {
			return $prefix."/".$newspath."/".$id;
		}
	}

	/**
	 * 获取分类
	 */
	static public function getNewsCategory($classId, $toutf8 = true) {
		$guid = sprintf("tganews_category_%s", md5(join("_", func_get_args())));
		$channel = self::getCacheHandler()->get($guid, self::CACHE_TIME);

		//need cache
		if (empty($channel)) {
			$channeldb = self::getModel('newsclass');
			$channel = $channeldb::findFirst(array(
				'classid = :classid:',
				'bind' => array(
					'classid' => $classId
				)
			));

			if ($channel != false) {
				$channel = $channel->toArray();
				if ($toutf8) {
					foreach ($channel as $k => $v) {
						$channel[$k] = iconv('gbk', 'utf-8', $v);
					}
				}

				self::getCacheHandler()->save($guid, $channel, self::CACHE_TIME);
			}
		}

		return $channel;
	}

	/**
	 * 获取新闻分类
	 * @parentClassId 总分类ID
	 * @isFull 是否获取分类中所有信息
	 * @orderby 排序, 如果要使用高级排序，isFull一定要设定为true
	 * @toutf8 是否需要转换编码
	 */
	private static $anonymous_functions = array();
	static public function getNewsCategories($parentClassId, $isFull = false, $orderby = " classid desc", $toutf8 = true) {
		$guid = sprintf("tganew_categories_%s", md5(join("_", func_get_args())));
		$data = self::getCacheHandler()->get($guid, self::CACHE_TIME);

		if (empty($data)) {
			$orderby = trim($orderby);
			list($element, $sort_key) = explode(" ", $orderby);

			$categories = array();
			$categoriesByGroup = array();

			$channeldb = self::getModel('newsclass');

			$channels = $channeldb::find(array(
				'bclassid = :bclassid:',
				'bind'    => array(
					'bclassid' => $parentClassId
				)
			));

			//获取有效的column
			$allow_sort_elements = $channeldb->getModelsMetaData()->getAttributes($channeldb);
			$is_allowed_sorting = in_array($element, $allow_sort_elements);
			
            $channels = $channels->toArray();
			for ($c = 0, $len = count($channels); $c < $len; $c++) {
				$channel = $channels[$c];

				if ($toutf8) {
					foreach ($channel as $k => $v) {
						$channel[$k] = iconv('gbk', 'utf-8', $v);
					}
					$className = $channel['classname'];
				} else {
					$className = $channel['classname'];
				}

				if ($isFull) {
					$category = $channel;
				} else {
					$category = array(
						'classid' => $channel['classid'],
						'classname' => $className,
						'classurl' => $channel['classurl']
					);
				}

				$categories[] = $category;

				if ($channel['islast'] == 0) {
					list($_categories, $_categoriesByGroup) = self::getNewsCategories($channel['classid'], $isFull, $orderby, $toutf8);
					$category['items'] = $_categoriesByGroup;
					$categories = array_merge($categories, $_categories);
				}
				$categoriesByGroup[] = $category;
			}

			if ($is_allowed_sorting && ($isFull || $element == 'classid')) {
				$sort_func = ($sort_key == 'desc') ? ('if ($a["'.$element.'"] > $b["'.$element.'"]) {return -1;} if ($a["'.$element.'"] < $b["'.$element.'"]) { return 1; }return 0;') : ('if ($a["'.$element.'"] > $b["'.$element.'"]) {return 1;} if ($a["'.$element.'"] < $b["'.$element.'"]) { return -1; }return 0;');
				$sort_func_hash = md5($sort_func);

				if (!isset(self::$anonymous_functions[$sort_func_hash])) {
					self::$anonymous_functions[$sort_func_hash] = create_function('$a, $b', $sort_func);
				}

				usort($categories, self::$anonymous_functions[$sort_func_hash]);
				usort($categoriesByGroup, self::$anonymous_functions[$sort_func_hash]);
			}

			$data = array($categories, $categoriesByGroup);
			self::getCacheHandler()->save($guid, $data, self::CACHE_TIME);
		}

		return $data;
	}
}

?>
